/*
 * Copyright (C) 2010 ST-Ericsson AS
 * Author: Erwan Bracq / erwan.bracq@stericsson.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 */

#include <mid_conf.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <libconfig.h>

#include <mid_log.h>
#include <mid_settings.h>
#include <mid_dev.h>
#ifdef MOTOROLA_FEATURE
#include <cutils/properties.h>
#endif

#define FW_UPGR_IMG_DIR "/data/firmware/st-ericsson/modem_fota"
#define FW_UPGR_FILE_NAME "FirmwareDeliveryPackage.upkg"

#define GPIO_CTRL_ENABLED 0
#define GPIO_CTRL_NOACLOW 0


int my_lookup_int(const config_t *config,
		  char* name,
		  int* value,
		  char* runtime_mode)
{
	char *new_name;
	if (strlen(runtime_mode)>0) {
		asprintf(&new_name,"%s_%s",runtime_mode, name);
		MLGD("CONF: lookup for %s option:", new_name);
		if (config_lookup_int(config, new_name,value)) {
			free(new_name);
			return 1;
		}
	}
	MLGD("CONF: lookup for %s option:", name);
	return config_lookup_int(config, name,value);
}

int my_lookup_bool(const config_t *config,
		   char* name,
		   int* value,
		   char* runtime_mode)
{
	char *new_name;
	if (strlen(runtime_mode)>0) {
		asprintf(&new_name,"%s_%s", runtime_mode, name);
		MLGD("CONF: lookup for %s option:", new_name);
		if (config_lookup_bool(config, new_name,value)) {
			free(new_name);
			return 1;
		}
	}
	MLGD("CONF: lookup for %s option:", name);
	return config_lookup_bool(config, name,value);
}

int my_lookup_string(const config_t *config,
		   char* name,
		   const char** value,
		   char* runtime_mode)
{
	const char* temp = NULL;
	int ret;

	// This function will make copies of the strings form libconfig, so
	// that they survive config_destroy.

	if (strlen(runtime_mode) > 0) {
		char *new_name;
		if (asprintf(&new_name,"%s_%s",runtime_mode, name) == -1) {
			MLGE("CONF: Failed to create runtime version of configuration option name. The option is not loaded.");
			return CONFIG_FALSE;
		}
		MLGD("CONF: lookup for %s option:", new_name);
		ret = config_lookup_string(config, new_name, &temp);
		free(new_name);
		if (ret == CONFIG_TRUE) {
			*value = strdup(temp);
			return ret;
		}
	}
	MLGD("CONF: lookup for %s option:", name);
	ret = config_lookup_string(config, name, &temp);
	if (ret == CONFIG_TRUE) {
		*value = strdup(temp);
	}
	return ret;
}

bool mid_conf_load(struct mid_config* config, const char* cfg_file)
{
	config_t cfg;
#if defined(MOTOROLA_FEATURE)
        char* bootmode;
#endif

	MLGD("CONF: Loading configuration from file: %s", cfg_file);

	/* Default not any specific runtime mode */
	config->runtime_mode=(char*)"";
	config->cpu_reset_reason=(char*)"";
	config->reboot_on_failure = 0;
	config->modem_arch = (char*)MODEM_ARCH_STRING;
	/* By default launch flash less boot sequence with no link switch */
	config->initial_enable_bootldr = 0;
	config->initial_rdir = RUNNING_DIR;
	config->fw_upgr_img_dir = FW_UPGR_IMG_DIR;
	config->fw_upgr_file_name = FW_UPGR_FILE_NAME;
	config->pidfile = MID_PID_FILE;
	/* Link swap for boot loader */
	config->link_switch = MID_ENABLE_LINKSWITCH;
	/* By default one attempt for IPC ops */
	config->boot_retry = MID_MAX_BOOT_ATTEMPT;
	config->flash_retry = MID_MAX_FLASH_ATTEMPT;
	config->shutdown_retry = MID_SHUTDOWN_RETRIES;
	/* By default no GPIO control */
	config->gpio_ctrl = MID_GPIO_CTRL;
	config->gpio_base_path="/sys/class/gpio";
	config->gpio_no_xport=0;
	config->gpio_no_dir=0;
	config->gpio_no_aclow = MID_GPIO_NOACL;
	/* By default open AT channel */
	config->enable_at_channel = 1;
	config->dump_timestamp = 0;
	config->dump_directory = NULL;
	config->dump_directory_header = NULL;
	config->silent_panic_detection_file = NULL;
	config->critical_panic_detection_file = NULL;
	config->dump_filename = DUMP_DEFAULT_FILENAME;
	config->dump_filename_header = DUMP_HEADER_DEFAULT_FILENAME;
	config->max_dump_files = MID_MAX_DUMP_FILES;
	/* Don't reboot host after binding security data */
	config->postsec_reboot = 0;
	config->initial_sec_data_conf = 0;
	/* 0 = OnSwA, power on(or off) by putting GPIO high for a few secconds */
	config->use_on_sw_c = 0;
	/* Don t use AT+CFUN=0 to shut down. But some old variant may need it */
	config->use_atcfun0 = 0;
	config->mfa_service_name = "mfa";
	config->mfa_start_command = "mfa &";
	config->mfa_stop_command = "killall mfa";
	config->mfa_control_path = "/dev/socket/mfa_control";

        config->mid_gpios[GPIO_ID_ON]=(struct gpio) {
                GPIO_MOD_ON, GPIO_MOD_ON_INIT_ST,
                GPIO_DIR_OUT, GPIO_MOD_ON_POL,
                GPIO_CTRL_ENABLED, GPIO_CTRL_NOACLOW
        };
        config->mid_gpios[GPIO_ID_RESET]=(struct gpio) {
                GPIO_MOD_RESET, GPIO_MOD_RESET_INIT_ST,
                GPIO_DIR_OUT, GPIO_MOD_RESET_POL,
                GPIO_CTRL_ENABLED, GPIO_CTRL_NOACLOW
        };
        config->mid_gpios[GPIO_ID_RESOUT2]=(struct gpio) {
                GPIO_MOD_RESOUT2, GPIO_MOD_RESOUT2_INIT_ST,
                    GPIO_DIR_IN, GPIO_MOD_RESOUT2_POL,
                    GPIO_CTRL_ENABLED, GPIO_CTRL_NOACLOW
        };
        config->mid_gpios[GPIO_ID_SERVICE]=(struct gpio) {
                GPIO_MOD_SERVICE, GPIO_MOD_SERVICE_INIT_ST,
                    GPIO_DIR_OUT, GPIO_MOD_SERVICE_POL,
                    GPIO_CTRL_ENABLED, GPIO_CTRL_NOACLOW
        };
        config->mid_gpios[GPIO_ID_PWRRSTIN]=(struct gpio) {
                GPIO_MOD_PWRRSTIN, GPIO_MOD_PWRRSTIN_INIT_ST,
                    GPIO_DIR_IN, GPIO_MOD_PWRRSTIN_POL,
                    GPIO_CTRL_ENABLED, GPIO_CTRL_NOACLOW
        };
        config->mid_gpios[GPIO_ID_PWRRSTOUT]=(struct gpio) {
                GPIO_MOD_PWRRSTOUT, GPIO_MOD_PWRRSTOUT_INIT_ST,
                    GPIO_DIR_OUT, GPIO_MOD_PWRRSTOUT_POL,
                    GPIO_CTRL_ENABLED, GPIO_CTRL_NOACLOW
        };

	config->prim_dev_config->internal = NULL;
	config->sec_dev_config->internal = NULL;

	/* Debug settings turned off by default */
	config->dbus_disable_modem_reboot = false;
	config->dbus_dump_on_reboot = false;

	config->timeout_flashing = 0;

	config_init(&cfg);

	if (!config_read_file(&cfg, cfg_file)) {
		MLGW("CONF: Warning, error in configuration file\n - "
				"configuration filename: %s\n - "
				"error on line: %d\n - error type: %s",
				config_error_file(&cfg),
				config_error_line(&cfg),
				config_error_text(&cfg));
		MLGW("CONF: No parameter are loaded. Default parameter are used.");
		return false;
	}

#if defined(MOTOROLA_FEATURE)
	MLGD("CONF: lookup for recovery_modem_prefl_cmd option:");
	config_lookup_string(&cfg, "recovery_modem_prefl_cmd",
		(const char **)&mot_mid_info.recovery_mod_prefl_cmd);
	mot_mid_info.recovery_mod_prefl_cmd = strdup(mot_mid_info.recovery_mod_prefl_cmd);
	MLGD("CONF: got-> %s.", mot_mid_info.recovery_mod_prefl_cmd);

	my_lookup_string(&cfg, "modem_mode_cmd",
		       &mot_mid_info.norm_mode_cmd,
		       "normal");
	my_lookup_string(&cfg, "modem_mode_cmd",
		       &mot_mid_info.itp_mode_cmd,
		       "itp");
	my_lookup_string(&cfg, "modem_mode_cmd",
		       &mot_mid_info.svc_mode_cmd,
		       "service");
	bootmode = malloc(PROPERTY_VALUE_MAX * sizeof(char));
	if (unlikely(!bootmode)) {
		MLGE("failed to allocate bootmode property");
		exit(EXIT_FAILURE);
	}
	property_get("ro.bootmode", bootmode, "");
	if (!strncmp(bootmode, "bp-service", PROPERTY_VALUE_MAX)) {
		config->runtime_mode = "service";
	} else {
#endif
	/* The runtime_mode should be lookup'ed first since the */
	/* my_lookup function will use this                     */
	MLGD("CONF: lookup for runtime_mode option:");
	config_lookup_string(&cfg, "runtime_mode",
			     (const char**)&config->runtime_mode);
	// Make a copy so that the value survives config_destroy
	config->runtime_mode = strdup(config->runtime_mode);
#if defined(MOTOROLA_FEATURE)
	}
	free(bootmode);
#endif
	MLGD("MID: MID running in runtime mode:%s.",config->runtime_mode);
#ifdef DEBUG_TRACE
	MLGD("MID: Starting from this point, the log verbosity is driven by log_debug_level option.");
	mid_dbg_info.mid_dbg_level = MID_LEVEL_MAX;
	my_lookup_int(&cfg, "log_debug_level",
		&mid_dbg_info.mid_dbg_level, config->runtime_mode);
	if (mid_dbg_info.mid_dbg_level > MID_LEVEL_MAX ||
		mid_dbg_info.mid_dbg_level <
		MID_LEVEL_MIN) {
		MLGW("CONF: Invalid debug level. Assume maximum debug output.");
		mid_dbg_info.mid_dbg_level = MID_LEVEL_MAX;
	}
	MLGD("CONF: lookup for log option:");
	if (my_lookup_string(&cfg, "log",
			     (const char **)&mid_dbg_info.logfile,
			     config->runtime_mode) == CONFIG_TRUE)
		mid_dbg_info.log_to_file = 1;
	MLGD("CONF: got-> %s.", mid_dbg_info.logfile);
#endif
	/* Then the modem arch should be indentified to load the correct library */
	MLGD("CONF: lookup for modem_arch option:");
	my_lookup_string(&cfg, "modem_arch",
			 (const char **)&config->modem_arch,
			 config->runtime_mode);
	MLGD("CONF: got-> %s.", config->modem_arch);
	MLGD("CONF: lookup for bootloader option:");
	my_lookup_bool(&cfg, "bootloader",
		       &config->initial_enable_bootldr,
		       config->runtime_mode);
	MLGD("CONF: got-> %d.", config->initial_enable_bootldr);

	MLGD("CONF: lookup for daemonize option:");
	my_lookup_bool(&cfg, "daemonize",
		       &config->daemonize,
		       config->runtime_mode);
	MLGD("CONF: got-> %d.", config->daemonize);
	my_lookup_string(&cfg, "modem_directory",
		(const char **)&config->initial_rdir, config->runtime_mode);
	MLGD("CONF: got-> %s.", config->initial_rdir);
	my_lookup_string(&cfg, "modem_fota_dir",
		(const char **)&config->fw_upgr_img_dir, config->runtime_mode);
	MLGD("CONF: got-> %s.", config->fw_upgr_img_dir);
	my_lookup_string(&cfg, "modem_fota_img_name",
		(const char **)&config->fw_upgr_file_name, config->runtime_mode);
	MLGD("CONF: got-> %s.", config->fw_upgr_file_name);
	MLGD("CONF: lookup for pid option:");
	my_lookup_string(&cfg, "pid",
			 (const char **)&config->pidfile,
			 config->runtime_mode);
	MLGD("CONF: got-> %s.", config->pidfile);
	my_lookup_string(&cfg, "primary_device",
		&config->prim_dev_config->name,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->prim_dev_config->name);
	if (my_lookup_string(&cfg, "secondary_device",
		&config->sec_dev_config->name,
		config->runtime_mode) == CONFIG_TRUE)
			config->link_switch = 1;
	MLGD("CONF: got-> %s.", config->sec_dev_config->name);
	MLGD("CONF: lookup for boot_retry option:");
	my_lookup_int(&cfg, "boot_retry",
		      &config->boot_retry,
		      config->runtime_mode);
	MLGD("CONF: got-> %d.", config->boot_retry);
	MLGD("CONF: lookup for flash_retry option:");
	my_lookup_int(&cfg, "flash_retry",
		      &config->flash_retry,
		      config->runtime_mode);
	MLGD("CONF: got-> %d.", config->flash_retry);
	MLGD("CONF: lookup for shutdown_retry option:");
	my_lookup_int(&cfg, "shutdown_retry",
		      &config->shutdown_retry,
		      config->runtime_mode);
	MLGD("CONF: got-> %d.", config->shutdown_retry);
	MLGD("CONF: lookup for flash_force_pwroff option:");
	my_lookup_bool(&cfg, "flash_force_pwroff",
		      &config->flash_force_pwroff,
		      config->runtime_mode);
	MLGD("CONF: got-> %d.", config->flash_force_pwroff);
	MLGD("CONF: lookup for gpio_ctrl option:");
	my_lookup_bool(&cfg, "gpio_ctrl",
		       &config->gpio_ctrl,
		       config->runtime_mode);
	MLGD("CONF: got-> %d.", config->gpio_ctrl);
	MLGD("CONF: lookup for gpio_base_path option:");
	config_lookup_string(&cfg, "gpio_base_path",
		(const char **)&config->gpio_base_path);
	config->gpio_base_path = strdup(config->gpio_base_path);
	MLGD("CONF: got-> %s.", config->gpio_base_path);
	MLGD("CONF: lookup for stub_gpio_xport_api option:");
	config_lookup_bool(&cfg, "stub_gpio_xport_api",
		&config->gpio_no_xport);
	MLGD("CONF: got-> %d.", config->gpio_no_xport);
	MLGD("CONF: lookup for stub_gpio_dir_api option:");
	config_lookup_bool(&cfg, "stub_gpio_dir_api",
		&config->gpio_no_dir);
	MLGD("CONF: got-> %d.", config->gpio_no_dir);
	MLGD("CONF: lookup for stub_aclow_api option:");
	config_lookup_bool(&cfg, "stub_aclow_api",
		&config->gpio_no_aclow);
	MLGD("CONF: got-> %d.", config->gpio_no_aclow);

	MLGD("CONF: lookup for gpio_on_id option:");
	config_lookup_int(&cfg, "gpio_on_id",
		&(config->mid_gpios[GPIO_ID_ON].gpio));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_ON].gpio);
	MLGD("CONF: lookup for gpio_on_aclow option:");
	config_lookup_bool(&cfg, "gpio_on_aclow",
		&(config->mid_gpios[GPIO_ID_ON].active_low));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_ON].active_low);
	MLGD("CONF: lookup for gpio_on_value option:");
	config_lookup_int(&cfg, "gpio_on_value",
		&(config->mid_gpios[GPIO_ID_ON].value));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_ON].value);

	MLGD("CONF: lookup for gpio_reset_id option:");
	config_lookup_int(&cfg, "gpio_reset_id",
		&(config->mid_gpios[GPIO_ID_RESET].gpio));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_RESET].gpio);
	MLGD("CONF: lookup for gpio_reset_aclow option:");
	config_lookup_bool(&cfg, "gpio_reset_aclow",
		&(config->mid_gpios[GPIO_ID_RESET].active_low));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_RESET].active_low);
	MLGD("CONF: lookup for gpio_reset_value option:");
	config_lookup_int(&cfg, "gpio_reset_value",
		&(config->mid_gpios[GPIO_ID_RESET].value));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_RESET].value);

	MLGD("CONF: lookup for gpio_rst2_id option:");
	config_lookup_int(&cfg, "gpio_rst2_id",
		&(config->mid_gpios[GPIO_ID_RESOUT2].gpio));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_RESOUT2].gpio);
	my_lookup_bool(&cfg, "gpio_rst2_aclow",
		&(config->mid_gpios[GPIO_ID_RESOUT2].active_low),
		config->runtime_mode);
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_RESOUT2].active_low);
	my_lookup_int(&cfg, "gpio_rst2_edge",
		&(config->mid_gpios[GPIO_ID_RESOUT2].value),
		config->runtime_mode);
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_RESOUT2].value);

	MLGD("CONF: lookup for gpio_service_id option:");
	config_lookup_int(&cfg, "gpio_serv_id",
		&(config->mid_gpios[GPIO_ID_SERVICE].gpio));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_SERVICE].gpio);
	my_lookup_bool(&cfg, "gpio_serv_aclow",
		&(config->mid_gpios[GPIO_ID_SERVICE].active_low),
		config->runtime_mode);
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_SERVICE].active_low);
	my_lookup_int(&cfg, "gpio_serv_value",
		&(config->mid_gpios[GPIO_ID_SERVICE].value),
		config->runtime_mode);
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_SERVICE].value);
	MLGD("CONF: lookup for gpio_pwrin_id option:");

	config_lookup_int(&cfg, "gpio_pwrin_id",
		&(config->mid_gpios[GPIO_ID_PWRRSTIN].gpio));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_PWRRSTIN].gpio);
	MLGD("CONF: lookup for gpio_pwrin_aclow option:");
	config_lookup_bool(&cfg, "gpio_pwrin_aclow",
		&(config->mid_gpios[GPIO_ID_PWRRSTIN].active_low));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_PWRRSTIN].active_low);
	MLGD("CONF: lookup for gpio_pwrin_edge option:");
	config_lookup_int(&cfg, "gpio_pwrin_edge",
		&(config->mid_gpios[GPIO_ID_PWRRSTIN].value));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_PWRRSTIN].value);

	MLGD("CONF: lookup for gpio_pwrout_id option:");
	config_lookup_int(&cfg, "gpio_pwrout_id",
		&(config->mid_gpios[GPIO_ID_PWRRSTOUT].gpio));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_PWRRSTOUT].gpio);
	MLGD("CONF: lookup for gpio_pwrout_aclow option:");
	config_lookup_bool(&cfg, "gpio_pwrout_aclow",
		&(config->mid_gpios[GPIO_ID_PWRRSTOUT].active_low));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_PWRRSTOUT].active_low);
	MLGD("CONF: lookup for gpio_pwrout_value option:");
	config_lookup_int(&cfg, "gpio_pwrout_value",
		&(config->mid_gpios[GPIO_ID_PWRRSTOUT].value));
	MLGD("CONF: got-> %d.", config->mid_gpios[GPIO_ID_PWRRSTOUT].value);

	my_lookup_string(&cfg, "modem_ifup_cmd",
		&config->mod_ifup_cmd,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->mod_ifup_cmd);
	my_lookup_string(&cfg, "modem_post_crashdump_cmd",
		&config->mod_post_crashdump_cmd,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->mod_post_crashdump_cmd);
	my_lookup_string(&cfg, "modem_pre_crashdump_cmd",
		&config->mod_pre_crashdump_cmd,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->mod_pre_crashdump_cmd);
	my_lookup_string(&cfg, "modem_postfl_cmd",
		&config->mod_postfl_cmd,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->mod_postfl_cmd);
	my_lookup_string(&cfg, "modem_prefl_cmd",
		&config->mod_prefl_cmd,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->mod_prefl_cmd);
	my_lookup_string(&cfg, "modem_on_cmd",
		&config->mod_on_cmd,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->mod_on_cmd);
	my_lookup_string(&cfg, "mfa_cmd",
		&config->mfa_cmd,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->mfa_cmd);
	my_lookup_string(&cfg, "modem_off_cmd",
		&config->mod_off_cmd,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->mod_off_cmd);
	my_lookup_string(&cfg, "modem_init_cmd",
		&config->mod_init_cmd,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->mod_init_cmd);
	MLGD("CONF: lookup for rfm_delay option:");
	my_lookup_int(&cfg, "rfm_delay",
		      &(config->rfm_delay),
		      config->runtime_mode);
	MLGD("CONF: got-> %d.", config->rfm_delay);
	my_lookup_bool(&cfg, "enable_mid_atchannel",
		&(config->enable_at_channel),
		config->runtime_mode);
	MLGD("CONF: got-> %d.", config->enable_at_channel);
	my_lookup_bool(&cfg, "enable_low_battery_subscription",
		&(config->enable_low_battery_subscription),
		config->runtime_mode);
	MLGD("CONF: got-> %d.", config->enable_low_battery_subscription);
	my_lookup_bool(&cfg, "enable_high_temperature_subscription",
		&(config->enable_high_temperature_subscription),
		config->runtime_mode);
	MLGD("CONF: got-> %d.", config->enable_high_temperature_subscription);
	MLGD("CONF: lookup for enable_efwd_atcfun option:");
	my_lookup_bool(&cfg, "enable_efwd_atcfun",
		       &(config->enable_efwd_atcfun),
		       config->runtime_mode);
	MLGD("CONF: got-> %d.", config->enable_efwd_atcfun);
	MLGD("CONF: lookup for enable_atcgmr option:");
	my_lookup_bool(&cfg, "enable_atcgmr",
		       &(config->enable_atcgmr),
		       config->runtime_mode);
	MLGD("CONF: got-> %d.", config->enable_atcgmr);
	MLGD("CONF: lookup for dump_directory option:");
	my_lookup_string(&cfg, "dump_directory",
		&config->dump_directory,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->dump_directory);
	MLGD("CONF: lookup for dump_directory_header option:");
	my_lookup_string(&cfg, "dump_directory_header",
		&config->dump_directory_header,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->dump_directory_header);
	MLGD("CONF: lookup for silent_panic_detection_file option:");
	my_lookup_string(&cfg, "silent_panic_detection_file",
		&config->silent_panic_detection_file,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->silent_panic_detection_file);
	MLGD("CONF: lookup for critical_panic_detection_file option:");
	my_lookup_string(&cfg, "critical_panic_detection_file",
		&config->critical_panic_detection_file,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->critical_panic_detection_file);
	MLGD("CONF: lookup for dump_filename option:");
	my_lookup_string(&cfg, "dump_filename",
		&config->dump_filename,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->dump_filename);
	MLGD("CONF: lookup for dump_filename_header option:");
	my_lookup_string(&cfg, "dump_filename_header",
		&config->dump_filename_header,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->dump_filename_header);
	MLGD("CONF: lookup for dump_timestamp option:");
	my_lookup_bool(&cfg, "dump_timestamp",
		&config->dump_timestamp,
		config->runtime_mode);
	MLGD("CONF: got-> %d.", config->dump_timestamp);
	MLGD("CONF: lookup for crash_dump_type option:");
	my_lookup_int(&cfg, "crash_dump_type",
		      &(config->crash_dump_type),
		      config->runtime_mode);
	MLGD("CONF: got-> %d.", config->crash_dump_type);
	MLGD("CONF: lookup for max_dump_files option:");
	my_lookup_int(&cfg, "max_dump_files",
		      &(config->max_dump_files),
		      config->runtime_mode);
	MLGD("CONF: got-> %d.", config->max_dump_files);
	MLGD("CONF: lookup for crashdump_dev_mode option:");
	my_lookup_int(&cfg, "crashdump_dev_mode", /* TEMPORARY */
		      &(config->crashdump_dev_mode),
		      config->runtime_mode);               /* TEMPORARY */
	MLGD("CONF: got-> %d.", config->crashdump_dev_mode);
	MLGD("CONF: lookup for post_security_reboot option:");
	my_lookup_bool(&cfg, "post_security_reboot",
		       &(config->postsec_reboot),
		       config->runtime_mode);
	MLGD("CONF: got-> %d.", config->postsec_reboot);
	MLGD("CONF: lookup for configure_sec_data option:");
	my_lookup_bool(&cfg, "configure_sec_data",
		       &config->initial_sec_data_conf,
		       config->runtime_mode);
	MLGD("CONF: got-> %d.", config->initial_sec_data_conf);
	MLGD("CONF: lookup for use_onSwC option:");
	my_lookup_bool(&cfg, "use_onSwC",
		       &(config->use_on_sw_c),
		       config->runtime_mode);
	MLGD("CONF: got-> %d.", config->use_on_sw_c);
	MLGD("CONF: lookup for use_atcfun0 option:");
	my_lookup_bool(&cfg, "use_atcfun0",
		       &(config->use_atcfun0),
		       config->runtime_mode);
	MLGD("CONF: got-> %d.", config->use_atcfun0);
	MLGD("CONF: lookup for force_gpio_pwroff option:");
	my_lookup_bool(&cfg, "force_gpio_pwroff",
		      &config->force_gpio_pwroff,
		      config->runtime_mode);
	MLGD("CONF: got-> %d.", config->force_gpio_pwroff);
	MLGD("CONF: lookup for modem_shutdown_mode option:");
	my_lookup_int(&cfg, "modem_shutdown_mode",
		      (int *)&(config->modem_shutdown_mode),
		      config->runtime_mode);
	MLGD("CONF: got-> %d.", config->modem_shutdown_mode);

	MLGD("CONF: lookup for reboot_on_failure option:");
	my_lookup_bool(&cfg, "reboot_on_failure",
		       &config->reboot_on_failure,
		       config->runtime_mode);
	MLGD("CONF: got-> %d.", config->reboot_on_failure);

	MLGD("CONF: lookup for cpu_reset_reason option:");
	config_lookup_string(&cfg, "cpu_reset_reason",
			     (const char**)&config->cpu_reset_reason);
	/* Make a copy so that the value survives config_destroy. */
	config->cpu_reset_reason = strdup(config->cpu_reset_reason);
	MLGD("CONF: got-> %s.", config->cpu_reset_reason);

	MLGD("CONF: lookup for use_cpu_reset_reg option:");
	my_lookup_bool(&cfg, "use_cpu_reset_reg",
		&config->use_cpu_reset_reg,
		config->runtime_mode);

	MLGD("CONF: lookup for dbus_disable_modem_reboot option:");
	my_lookup_bool(&cfg, "dbus_disable_modem_reboot",
		      (int *)&(config->dbus_disable_modem_reboot),
		      config->runtime_mode);
	MLGD("CONF: got-> %d.", config->dbus_disable_modem_reboot);
	MLGD("CONF: lookup for dbus_dump_on_reboot option:");
	my_lookup_bool(&cfg, "dbus_dump_on_reboot",
		      (int *)&(config->dbus_dump_on_reboot),
		      config->runtime_mode);
	MLGD("CONF: got-> %d.", config->dbus_dump_on_reboot);

	my_lookup_int(&cfg, "state_flashing_timeout",
		&config->timeout_flashing, config->runtime_mode);
	MLGD("CONF: got-> %d.", config->timeout_flashing);

	my_lookup_string(&cfg, "mfa_service_name",
		&config->mfa_service_name,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->mfa_service_name);

	my_lookup_string(&cfg, "mfa_start_command",
		&config->mfa_start_command,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->mfa_start_command);

	my_lookup_string(&cfg, "mfa_stop_command",
		&config->mfa_stop_command,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->mfa_stop_command);

	my_lookup_string(&cfg, "mfa_control_path",
		&config->mfa_control_path,
		config->runtime_mode);
	MLGD("CONF: got-> %s.", config->mfa_service_name);

	if (strlen(config->runtime_mode) == 0) {
		MLGW("MID: No runtime mode defined. Will assume \"normal\".");
		config->runtime_mode = "normal";
	}

	/* Get the modem ARCH converted to id */
	config->modem_arch_id = UNKNOWN;
	if (strcmp(config->modem_arch, "OSMIUM") == 0)
		config->modem_arch_id = OSMIUM;
	if (strcmp(config->modem_arch, "HASSIUM") == 0)
		config->modem_arch_id = HASSIUM;
	if (strcmp(config->modem_arch, "THORIUM") == 0)
		config->modem_arch_id = THORIUM;

	config_destroy(&cfg);

	return true;
}
